package com.shuai.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuai.enums.ErrorEnum;
import com.shuai.exception.SystemException;
import com.shuai.mapper.*;
import com.shuai.model.converter.SysUserConverter;
import com.shuai.model.converter.UserDetailInfoConverter;
import com.shuai.model.form.AllotForm;
import com.shuai.model.loginInfo.UserDetailInfo;
import com.shuai.model.po.*;
import com.shuai.model.query.SysUserQuery;
import com.shuai.model.vo.SysUserVo;
import com.shuai.service.SysUserService;
import com.shuai.utils.converter.PageConverter;
import com.shuai.utils.data.DataUtil;
import com.shuai.utils.user.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户信息 服务实现类
 *
 * @author shuai
 * @since 2022
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService, UserDetailsService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysPermissionMapper sysPermissionMapper;

    @Resource
    private SysRolePermissionMapper sysRolePermissionMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws SystemException {
        //查询用户信息
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
        SysUser user = sysUserMapper.selectOne(wrapper.eq(SysUser::getUsername, username));
        if (ObjectUtil.isEmpty(user)) {
            throw new SystemException(String.format(ErrorEnum.ERROR_USER_NAME.getMsg(),username));
        }
        UserDetailInfo userDetailInfo = UserDetailInfoConverter.convertToUserDetailInfoByPo(user);
        // 查询当前用户的所有角色和权限
        this.getAllRoleAndPermission(userDetailInfo);
        return userDetailInfo;
    }

    /**
     * 获取用户的角色与权限
     *
     * @param userDetailInfo
     * @return
     */
    private void getAllRoleAndPermission(UserDetailInfo userDetailInfo) {
        //获取用户的角色id
        LambdaQueryWrapper<SysUserRole> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysUserRole::getUserId,userDetailInfo.getId());
        List<Long> roleIds = sysUserRoleMapper.selectList(wrapper).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(roleIds)) {
            //获取用户角色
            userDetailInfo.setRoles(roleIds.stream().map(String::valueOf).collect(Collectors.toList()));
            //获取用户权限
            LambdaQueryWrapper<SysRolePermission> roleWrapper = Wrappers.lambdaQuery();
            roleWrapper.in(ObjectUtil.isNotEmpty(roleIds),SysRolePermission::getRoleId,roleIds);
            Set<Long> permissionIds = sysRolePermissionMapper.selectList(roleWrapper).stream().map(SysRolePermission::getPermissionId).collect(Collectors.toSet());
            //登录用户菜单
            List<SysPermission> permissionList = sysPermissionMapper.selectBatchIds(permissionIds);
            List<String> menus = permissionList.stream().filter(item -> item.getCode() != null & item.getType() != 2).map(SysPermission::getCode).collect(Collectors.toList());
            userDetailInfo.setMenus(menus);
            // 获取登录用户权限
            List<String> permissions = permissionList.stream().filter(item -> item.getCode() != null & item.getType() == 2).map(SysPermission::getCode).collect(Collectors.toList());
            userDetailInfo.setPermissions(permissions);

//            //使用@PreAuthorize("hasAuthority('sys:user:edit')")控制权限
//            String[] strings = permissions.toArray(new String[permissions.size()]);
//            List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(strings);
//            userDetailInfo.setAuthorities(authorityList);
        }
//        return userDetailInfo;
    }

    @Override
    public UserDetailInfo getUserInfo() {
        return UserUtil.getUserInfo();
//       return this.getAllRoleAndPermission(UserUtil.getUserInfo());
    }

    @Override
    public Integer addSysUser(SysUser sysUser) {
        //设置默认账号密码
        sysUser.setPassword(UserUtil.getUserPassWord());
        return sysUserMapper.insert(sysUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteSysUser(SysUserQuery query) {
        //通过userId删除用户的角色关系表
        LambdaQueryWrapper<SysUserRole> wrapper = Wrappers.lambdaQuery();
        wrapper.in(SysUserRole::getUserId,query.getIds());
        sysUserRoleMapper.delete(wrapper);
        return sysUserMapper.deleteBatchIds(query.getIds());
    }

    @Override
    public Integer editSysUser(SysUser sysUser) {
        return sysUserMapper.updateById(sysUser);
    }

    @Override
    public List<SysUserVo> selectList(SysUserQuery query) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper();
        fillQueryWrapper(queryWrapper, query);
        List<SysUser> userList = sysUserMapper.selectList(queryWrapper);
        return SysUserConverter.convertToVoByPo(userList);
    }

    @Override
    public IPage<SysUserVo> selectPage(SysUserQuery query) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper();
        fillQueryWrapper(queryWrapper, query);
        Page<SysUser> page = new Page<>(query.getPage(), query.getLimit());
        IPage<SysUser> pageList = sysUserMapper.selectPage(page, queryWrapper);
        List<SysUserVo> records = SysUserConverter.convertToVoByPo(pageList.getRecords());
        return PageConverter.convertToPage(pageList, records);
    }

    @Override
    public SysUserVo selectById(Long id) {
        SysUser user = sysUserMapper.selectById(id);
        return SysUserConverter.convertToVoByPo(user);
    }

    @Override
    public boolean checkUsername(String username) {
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysUser::getUsername, username);
        SysUser user = sysUserMapper.selectOne(wrapper);
        return ObjectUtil.isNotEmpty(user) ? false : true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void allotRole(AllotForm form) {
        LambdaQueryWrapper<SysUserRole> wrapper = Wrappers.lambdaQuery();
        wrapper.in(SysUserRole::getUserId, form.getUserId());
        sysUserRoleMapper.delete(wrapper);
        Arrays.stream(form.getRoleIds()).forEach(roleId->{
            SysUserRole userRole = SysUserRole.builder().userId(form.getUserId()).roleId(Long.parseLong(roleId)).build();
            sysUserRoleMapper.insert(userRole);
        });
    }


    /**
     * 生成查询条件与排序
     *
     * @param query
     * @return
     */
    private void fillQueryWrapper(QueryWrapper<SysUser> queryWrapper, SysUserQuery query) {
        //组织查询条件
        queryWrapper.lambda()
                .like(StrUtil.isNotEmpty(query.getUsernameLike()), SysUser::getUsername, query.getUsernameLike())
                .like(StrUtil.isNotEmpty(query.getRealNameLike()), SysUser::getRealName, query.getRealNameLike())
        ;

        //生成order by 的语句
        DataUtil.fillOrderBy(query, queryWrapper, SysUser.class);
    }

}
